package org.tis.tools.starter.operatelog.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.annotations.TableId;
import org.apache.commons.lang3.StringUtils;
import org.tis.tools.starter.operatelog.exception.OperateLogException;
import org.tis.tools.starter.operatelog.exception.OperateLogExceptionCodes;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * description:
 *
 * @author zhaoch
 * @date 2018/5/16
 **/
public class DataUtils {

    /**
     * 实体类默认生成一个名为 NAME 的静态常量，值为实体逻辑名称
     *
     * 如Employee类有：
     * public static fianl String NAME = "员工"
     */
    private static final String DATA_NAME = "NAME";

    /**
     * 获取实体对象的ID，反射获取带有{@link TableId}注解的属性值
     * @param object
     * @return
     * @throws IllegalAccessException
     */
    public static String getEntityId(Object object) {
        String id = null;
        TableId annotation = null;
        Field[] declaredFields = object.getClass().getDeclaredFields();
        for (Field f : declaredFields) {
            annotation = f.getAnnotation(TableId.class);
            if (annotation != null) {
                f.setAccessible(true);
                try {
                    id = (String) f.get(object);
                    break;
                } catch (IllegalAccessException ignored) {

                }
            }
        }
        if (annotation == null) {
            throw new OperateLogException(OperateLogExceptionCodes.NOT_FOUND_ENTITY_ID_ANNOTATION);
        } else if (StringUtils.isBlank(id)) {
            throw new OperateLogException(OperateLogExceptionCodes.ENTITY_ID_IS_BLANK);
        }
        return id;
    }

    /**
     * 获取实体类的逻辑名称，反射获指定属性名称{@link DataUtils#DATA_NAME}的属性值
     * @param clazz
     * @return
     */
    public static String getEntityName(Class clazz) {
        try {
            return (String) clazz.getField(DATA_NAME).get(null);
        } catch (Exception e) {
            throw new OperateLogException(OperateLogExceptionCodes.NOT_FOUND_ENTITY_NAME);
        }
    }

    /**
     * 将驼峰式命名的字符串转换为下划线大写方式。如果转换前的驼峰式命名的字符串为空，则返回空字符串。</br>
     * 例如：HelloWorld->HELLO_WORLD
     * @param name 转换前的驼峰式命名的字符串
     * @return 转换后下划线大写方式命名的字符串
     */
    public static String camel2Underline(String name) {
        StringBuilder result = new StringBuilder();
        if (name != null && name.length() > 0) {
            // 将第一个字符处理成大写
            result.append(name.substring(0, 1).toUpperCase());
            // 循环处理其余字符
            for (int i = 1; i < name.length(); i++) {
                String s = name.substring(i, i + 1);
                // 在大写字母前添加下划线
                if (s.equals(s.toUpperCase()) && !Character.isDigit(s.charAt(0))) {
                    result.append("_");
                }
                // 其他字符直接转成大写
                result.append(s.toUpperCase());
            }
        }
        return result.toString();
    }

    /**
     * 序列化对象值为JSON
     * @param object
     * @return
     */
    public static String getDataString(Object object) {
        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(object));
        List<Map> fields = new ArrayList<>();
        jsonObject.forEach((s, o) -> {
            Map<String, Object> field = new HashMap<>();
            field.put("field", s);
            field.put("value", o);
            try {
                Field f = object.getClass().getField("NAME_" + DataUtils.camel2Underline(s));
                f.setAccessible(true);
                field.put("name", f.get(object));
            } catch (NoSuchFieldException | IllegalAccessException ignored) {

            }
            fields.add(field);
        });
        return JSON.toJSONString(fields);
    }


}
